package com.lecyon.farm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.lecyon.farm.base.BaseResponse;
import com.lecyon.farm.common.constant.CommonConstant;
import com.lecyon.farm.common.constant.FarmSysConstant;
import com.lecyon.farm.common.exception.FarmException;
import com.lecyon.farm.entity.FmAlreadySyncRecords;
import com.lecyon.farm.mapper.FmAlreadySyncRecordsMapper;
import com.lecyon.farm.service.IFmAlreadySyncRecordsService;
import com.lecyon.farm.util.RedisUtils;
import com.lecyon.farm.util.ResultUtil;
import com.lecyon.farm.util.StringHelper;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotBlank;
import java.util.List;

/**
 * 已完成同步的记录  服务实现类
 *
 * @author YaoZheng
 * @since 2020-04-16
 */
@Service
@Validated
public class FmAlreadySyncRecordsServiceImpl extends ServiceImpl<FmAlreadySyncRecordsMapper, FmAlreadySyncRecords> implements IFmAlreadySyncRecordsService {

    private static final Logger LOG = LoggerFactory.getLogger(FmAlreadySyncRecordsServiceImpl.class);

    private RedisUtils redisUtils;

    /**
     * 记录已同步的信息
     *
     * @param fmAlreadySyncRecordsList
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse recordSyncInfo(List<FmAlreadySyncRecords> fmAlreadySyncRecordsList, String sourceTableName, String methodName) {
        if (CollectionUtils.isEmpty(fmAlreadySyncRecordsList)) {
            return ResultUtil.success();
        }
        //校验list中的元素表名是否与传入表名一致
        String contentTableName;
        String contentMethodName;
        List<FmAlreadySyncRecords> removeExistingRecordList = Lists.newLinkedList();
        boolean existFlag;
        for (FmAlreadySyncRecords fmAlreadySyncRecords : fmAlreadySyncRecordsList) {
            contentTableName = fmAlreadySyncRecords.getSourceTableName();
            contentMethodName = fmAlreadySyncRecords.getMethodName();
            if (StringHelper.isEmpty(contentTableName) || !sourceTableName.equals(contentTableName)) {
                // 元素中表名为空或者与传入表名不一致
                return ResultUtil.error(CommonConstant.EX_FORM_VALIDATE_ERROR, "表名不一致");
            }
            if (StringHelper.isEmpty(contentMethodName) || !methodName.equals(contentMethodName)) {
                // 元素中方法名为空或者与传入方法名不一致
                return ResultUtil.error(CommonConstant.EX_FORM_VALIDATE_ERROR, "方法名不一致");
            }
            existFlag = isExist(fmAlreadySyncRecords.getSourceId(), fmAlreadySyncRecords.getSourceTableName(), fmAlreadySyncRecords.getMethodName());
            if (!existFlag) {
                removeExistingRecordList.add(fmAlreadySyncRecords);
            }
        }
        boolean flag = saveBatch(removeExistingRecordList);
        if (!flag) {
            throw new FarmException(CommonConstant.EX_DB_INSERT_ERROR, "记录已同步信息失败！");
        }
        // 查询数据库表得到最新的 fmAlreadySyncRecordsList
        QueryWrapper<FmAlreadySyncRecords> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("source_table_name", sourceTableName);
        fmAlreadySyncRecordsList = list(queryWrapper);
        flag = redisUtils.hHasKey(FarmSysConstant.REDIS_KEY_ALREADY_RECORD_SYNC_INFO, sourceTableName);
        if (flag) {
            redisUtils.hDel(FarmSysConstant.REDIS_KEY_ALREADY_RECORD_SYNC_INFO, sourceTableName);
        }
        flag = redisUtils.hSet(FarmSysConstant.REDIS_KEY_ALREADY_RECORD_SYNC_INFO, sourceTableName, fmAlreadySyncRecordsList);
        if (!flag) {
            throw new FarmException(CommonConstant.EX_DB_REDIS_ERROR, "系统缓存异常！");
        }
        return ResultUtil.success();
    }

    /**
     * 获取已同步的信息的记录
     *
     * @return
     */
    private List<FmAlreadySyncRecords> getAll(String sourceTableName) {
        List<FmAlreadySyncRecords> result;
        QueryWrapper<FmAlreadySyncRecords> queryWrapper = new QueryWrapper<>();
        if (StringHelper.isNotEmpty(sourceTableName)) {
            queryWrapper.eq("source_table_name", sourceTableName);
        }
        result = list(queryWrapper);
        return result;
    }

    /**
     * 获取已同步的信息的记录
     *
     * @return
     */
    private List<FmAlreadySyncRecords> getAll(String sourceTableName, String methodName) {
        List<FmAlreadySyncRecords> result;
        QueryWrapper<FmAlreadySyncRecords> queryWrapper = new QueryWrapper<>();
        if (StringHelper.isNotEmpty(sourceTableName)) {
            queryWrapper.eq("source_table_name", sourceTableName);
        }
        if (StringHelper.isNotEmpty(methodName)) {
            queryWrapper.eq("method_name", methodName);
        }
        result = list(queryWrapper);
        return result;
    }

    /**
     * 获取已同步的信息的记录(区分表名)
     *
     * @param sourceTableName 源表名
     * @return
     */
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public List<String> getAlreadyRecordIds(String sourceTableName) {
//        List<String> result;
//        // 获取已经同步过的记录信息
//        List<FmAlreadySyncRecords> transformResult = getAll(sourceTableName);
//        result = Lists.newArrayList();
//        if (CollectionUtils.isNotEmpty(transformResult)) {
//            transformResult.stream().forEach(item -> result.add(item.getSourceId()));
//        }
//        return result;
//    }

    /**
     * 获取已同步的信息的记录(区分表名)
     *
     * @param sourceTableName 源表名
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<String> getAlreadyRecordIds(String sourceTableName, String methodName) {
        List<String> result;
        // 获取已经同步过的记录信息
        List<FmAlreadySyncRecords> transformResult = getAll(sourceTableName, methodName);
        result = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(transformResult)) {
            transformResult.stream().forEach(item -> result.add(item.getSourceId()));
        }
        return result;
    }

    /**
     * 判断数据是否已经存在
     *
     * @param sourceId    源表id
     * @param sourceTable 源表名
     * @return
     */
    private boolean isExist(@NotBlank String sourceId, @NotBlank String sourceTable, String methodName) {
        QueryWrapper<FmAlreadySyncRecords> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("source_id", sourceId).eq("source_table_name", sourceTable);
        if (StringHelper.isNotEmpty(methodName)) {
            queryWrapper.eq("method_name", methodName);
        }
        int count = count(queryWrapper);
        return count > 0 ? true : false;
    }

    /**
     * ----------------------------- 分割线 以下是setter方法，用于替换field上的@Autowired -----------------------------
     **/
    @Autowired
    @Lazy
    public void setRedisUtils(RedisUtils redisUtils) {
        this.redisUtils = redisUtils;
    }
}
